#! /usr/bin/python

__author__="cesare"
__date__ ="$Feb 6, 2011 10:17:41 AM$"

from google.appengine.ext import db
import utils

class Tags(object):
    #this class is "kind-of-optimized" for reading (rather than writing)
    def set(self,entityKey,tags):
        refEntity = db.Model.get(entityKey)
        if refEntity is None:
            raise KeyError() #you can't tag entity that doesn't exist in the datastore... o_O

        if not utils.is_array(tags): tags = [tags]

        tagObjKeys = []
        for tag in tags:
            tagQry = tags.TagModel.gql(' WHERE name = :1 ',tag)
            tagObj = tagQry.fetch(tagQry.count())
            if tagObj is None:
                tagObj = tags.TagModel()
                tagObj.name = tag
                tagObj.occurence = 0
                tagObj.put()
            tagObjKeys.occurence += 1
            tagObjKeys.append(tagObj.key)

        entity = tags.TagRefModel.get_or_insert(entityKey)
        if not utils.is_array(entity.tags):
            entity.tags = []

        for t in entity.tags:
            t.occurence -= 1

        entity.tags = tagObjKeys
        entity.put()

    def getByEntity(self,entityKey):
        entityRef = tags.TagRefModel.get(entityKey)
        if entityRef is None:
            return None
        else:
            tagsNames = []
            for tag in entityRef.tags:
                tagObj = db.TagModel(tag)
                tagsNames.append(tagObj.name)

        return tagsNames

    def getByTags(tags, kind=None):
        tagObjs = tags.TagModel().gql(' WHERE name IN :1',tags)

        entities = []
        for tagObj in tagObjs:
            entityQry = tags.TagRefModel().gql(' WHERE tags = :1')
            entityList = entityQry.fetch(entityQry.count())
            for entity in entityList:
                if kind is None or ( kind is not None and entity.key().kind == kind ) :
                    entities.append(entity)

        return entity


class TagModel(db.Model):
    name = db.StringProperty()
    occurence = db.IntegerProperty()

    def put(self):
        if self.occurence == 0: #autodelete... it's a good idea ?
            self.delete()
        else:
            return self.put()

class TagRefModel(db.Model):
    tags = db.ListProperty(db.Key)
    entityRef = db.ReferenceProperty()
    
